class_name Manager
extends BaseSystem

# 全局游戏管理类，管理游戏状态等

class UpTipInfo:
	var up_tip:UpTip
	var timer:CustomTimer
	func _init(up_tip:UpTip,timer:CustomTimer) -> void:
		self.up_tip = up_tip
		self.timer = timer
#region 属性
@export var game_mode:GameEnum.GameMode = GameEnum.GameMode.Dev
@export var seed:int = 0
@export var popup_tip_scene:PackedScene
@export var max_up_tip_amount:int = 3
@export var up_tip_scene:PackedScene
## 这个只是为了给物理检测供world_2d的
@export var physice_check_world_2d:Node2D
var _last_game_state:GameEnum.GameState = GameEnum.GameState.Null
var _cur_game_state:GameEnum.GameState = GameEnum.GameState.Null
var grng:GameRandomNumberGenerator
var up_tip_queue:Array[UpTipInfo] = []
var gm_dict:Dictionary = {}
#endregion
#region 字段
#endregion
#region 信号
signal game_state_changed(cur_game_state:GameEnum.GameState)
#endregion

#region 基类方法
func init_system(args = null):
	super(args)
	grng = GameRandomNumberGenerator.new(seed)
	## 一开始不依赖固定种子随机
	grng.grng_randomize()
#endregion
#region 公共方法
# 开始游戏
func start_game():
	## 生成大厅
	var cur_map = GameMapSystem.get_map_manager().create_map_by_id("10001")
	## 生成人物并传送到大厅
	GamePlayerSystem.create_player()
	if cur_map:
		var waiting_room:BaseRoom = cur_map.get_rooms_by_type(GameEnum.RoomType.WaitingRoom)[0]
		if waiting_room:
			waiting_room.add_child(GamePlayerSystem.player)
			GamePlayerSystem.translate_player(waiting_room.get_birth_pos())
			GameViewSystem.open_view(GameEnum.ViewType.LoadingView,{TargetView = GameEnum.ViewType.GamingView})
# 继续游戏
func continue_game():
	pass
# 退出游戏
func quit_game():
	get_tree().quit()
	pass
# 返回主界面
func back_to_main_menu():
	pass
func change_cur_game_state(game_state:GameEnum.GameState):
	_cur_game_state = game_state
	game_state_changed.emit(_cur_game_state)
func get_cur_game_state() -> GameEnum.GameState:
	return _cur_game_state
func get_grng():
	if not grng:
		grng = GameRandomNumberGenerator.new(seed)
	return grng
func translate_last_game_state():
	translate_game_state(_last_game_state)
func get_last_game_state() -> GameEnum.GameState:
	return _last_game_state
func translate_game_state(next_game_state:GameEnum.GameState):
	if _cur_game_state == next_game_state:
		return
	_last_game_state = _cur_game_state
	_cur_game_state = next_game_state
#region Tip
## 顶部浮字
func float_tip(tip:String, duration:float = 1):
	var valid_up_tip_queue:Array[UpTipInfo] = []
	for info:UpTipInfo in up_tip_queue:
		if is_instance_valid(info.up_tip):
			valid_up_tip_queue.push_back(info)
	up_tip_queue = valid_up_tip_queue
	if up_tip_queue.size() >= max_up_tip_amount:
		var up_tip_info:UpTipInfo = up_tip_queue.pop_front()
		if up_tip_info:
			up_tip_info.up_tip.hide_tip()
			GameCustomTimerSystem.remove_timer(up_tip_info.timer.id)
	var new_up_tip:UpTip = up_tip_scene.instantiate()
	var new_timer = GameCustomTimerSystem.create_timer(duration)
	var new_up_tip_info:UpTipInfo = UpTipInfo.new(new_up_tip,new_timer)
	up_tip_queue.push_back(new_up_tip_info)
	new_up_tip_info.up_tip.show_tip(tip)
	new_timer.register_listener(new_timer.timer_finished,func(timer_result:CustomTimer.TimerResult):
		new_up_tip_info.up_tip.hide_tip()
	)
	%UpTipBox.add_child(new_up_tip)
	GameCustomTimerSystem.start_timer(new_timer.id)
## 飘字
func popup_tip(tip:String,pos:Vector2,tip_color:Color = Color.WHITE):
	if not tip.is_empty():
		var popup_tip:PopupTip = popup_tip_scene.instantiate()
		var final_tip = tip
		if tip_color != Color.WHITE:
			final_tip = "[color={0}]{1}[/color]".format([tip_color.to_html(true),tip])
		popup_tip.init_text(final_tip)
		popup_tip.global_position = pos
		%PopupTip.add_child(popup_tip)
## 添加GM按钮及其方法
func add_gm_btn(label:String,pressed_callback:Callable,icon:Texture2D = null):
	var popup:PopupMenu = %GMMenuButton.get_popup()
	var id = gm_dict.keys().size()
	if icon:
		popup.add_icon_item(icon,label,id)
	else:
		popup.add_item(label,id)
	gm_dict[id] = pressed_callback
## 添加GM分割线
func add_gm_separator(label:String = ""):
	var popup:PopupMenu = %GMMenuButton.get_popup()
	popup.add_separator(label)
#endregion
#endregion
#endregion
#region 私有方法
## 更新GM
func _update_gm():
	var popup:PopupMenu = %GMMenuButton.get_popup()
	popup.clear(true)
	# TODO GM方法添加放在下面
	add_gm_btn("A",func():print(1))
	add_gm_separator()
	add_gm_btn("B",func():print(2))
	
	popup.id_pressed.connect(_on_gm_pressed)
func _on_gm_pressed(id:int):
	if %GMMenuButton.visible:
		if gm_dict.has(id):
			gm_dict[id].call()
#endregion
#region 生命周期函数
func _init() -> void:
	GameEventBus.GameSystemInited.connect(_update_gm)
func _ready() -> void:
	change_cur_game_state(GameEnum.GameState.MainMenu)
	# 目前只有Dev版本显示FPS
	if game_mode == GameEnum.GameMode.Dev:
		%FPSLab.visible = true
	else:
		%FPSLab.visible = false
	%GMMenuButton.visible = game_mode == GameEnum.GameMode.Dev or game_mode == GameEnum.GameMode.Test
func _process(delta: float) -> void:
	if game_mode == GameEnum.GameMode.Dev:
		%FPSLab.text = "FPS:{0}".format([str(Engine.get_frames_per_second())])
func _notification(what: int) -> void:
	if what == NOTIFICATION_WM_CLOSE_REQUEST:
		# TODO 退出游戏前需要做的放这
		pass
#endregion
